# -*- coding: utf-8 -*-
'''
  @author zhanghaisheng
  @date 2021/8/20
  @description get sonar_code_scan result
'''
import os
import sys
import json
import urllib3
import requests
from requests.auth import HTTPBasicAuth
from ci_conclude.const import CODE
from ci_conclude.base import BaseConclude
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class SonarConclude(BaseConclude):
    token = "f59b23e18b3a6874860e8ca333176a3d3d884395"

    def __init__(self, *args, **kwargs):
        super(SonarConclude, self).__init__(*args, **kwargs)
        self.componentKeys = self.component = self.project_name

    def exec_cmd(self, cmd):
        if cmd is not None:
            pip = os.popen(cmd) 
            res = pip.buffer.read().decode(encoding='utf8')
            return res
        else:
            return 'cmd is none!'
    
    def exec_req(self, types='BUG'):
        url = f'https://sonar.ecarxgroup.com/api/issues/search?componentKeys={self.componentKeys}&s=FILE_LINE&resolved=false&types={types}&ps=100&facets=owaspTop10%2CsansTop25%2Cseverities%2CsonarsourceSecurity%2Ctypes%2Cscopes%2Cresolutions&additionalFields=_all&timeZone=Asia%2FShanghai'
        res = requests.post(url, verify=False, auth=HTTPBasicAuth(self.token, ''))
        return res.json()
    
    @property
    def bug_results(self):
        j1 = self.exec_req()
        types = [d for d in j1["facets"] if d["property"] == 'types']
        severities = [d for d in j1["facets"] if d["property"] == 'severities']
        types_values = {d["val"]:d["count"] for d in types[0]["values"]}
        severities_values = {d["val"]:d["count"] for d in severities[0]["values"]}
        _bug_results = {}
        _bug_results.update(types_values)
        _bug_results.update(severities_values)
        return _bug_results

    @property
    def code_smell_results(self):
        j1 = self.exec_req(types='CODE_SMELL')
        types = [d for d in j1["facets"] if d["property"] == 'types']
        severities = [d for d in j1["facets"] if d["property"] == 'severities']
        types_values = {d["val"]:d["count"] for d in types[0]["values"]}
        severities_values = {d["val"]:d["count"] for d in severities[0]["values"]}
        _bug_results = {}
        _bug_results.update(types_values)
        _bug_results.update(severities_values)
        return _bug_results


    # def request(url, method='GET', data=None, header={}):
    #     if method == 'GET':
    #         request = urllib.request.Request(url)
    #         response = urllib.request.urlopen(request)
    #         resraw = response.read()
    #         return resraw
    #     elif method == 'POST':
    #         request = urllib.request.Request(url, data.encode('utf-8'), header, method='POST')
    #         response = urllib.request.urlopen(request)
    #         resraw = response.read()
    #         return resraw
    #     else:
    #         return  None

    def get_sonar_meric_number(self, metric_key):
        url_get_metric = f"https://sonar.ecarxgroup.com/api/measures/component?component={self.componentKeys}&metricKeys={metric_key}"
        cmd_get_metric = f"curl -s -u {self.token}: '{url_get_metric}'"
        response = self.exec_cmd(cmd_get_metric)
        if 'value' in response:
            if metric_key == 'new_bugs':
                return json.loads(response)['component']['measures'][0]['periods'][0]['value']
            else:
                return json.loads(response)['component']['measures'][0]['value']
        else:
            return None

    def get_sonar_severity_number(self, severity):
        url_get_severity = f"https://sonar.ecarxgroup.com/api/issues/search?componentKeys={self.componentKeys}&severities={severity}&types=BUG"
        cmd_get_severity = f"curl -s -u {self.token}: '{url_get_severity}'"
        print(cmd_get_severity)
        response = self.exec_cmd(cmd_get_severity)
        if 'total' and 'paging' in response:
            # return json.loads(response.split(',')[0] + '}')['total']
            # fixed = len(response.split('FIXED')) - 1  # 已修复问题数
            fixed = len(response.split('CLOSED')) - 1  # 已修复问题数
            return str(int(response.split(',')[0].split(':')[1]) - fixed)
        else:
            return None

    def get_sonar_status(self):
        url_get_status = f"https://sonar.ecarxgroup.com/api/qualitygates/project_status?projectKey={self.componentKeys}"
        cmd_get_status = f"curl -s -u {self.token}: '{url_get_status}'"
        response = self.exec_cmd(cmd_get_status)
        if 'status' in response:
            return json.loads(response)['projectStatus']['status']
        else:
            return None
    
    def get_url(self):
        sonar_url = f"https://sonar.ecarxgroup.com/dashboard?id={self.project_name}" #sonar平台项目链接
        return sonar_url

    def get_result(self):
        # blocker = self.get_sonar_severity_number('BLOCKER') # 阻塞数量
        # blocker = 0 if blocker is None else blocker
        blocker = self.bug_results.get("BLOCKER", 0)
        
        # critical = self.get_sonar_severity_number('CRITICAL') # 严重数量
        # critical = 0 if critical is None else critical
        critical = self.bug_results.get("CRITICAL", 0)
        
        # major = self.get_sonar_severity_number('MAJOR') # 主要数量
        # major = 0 if major is None else major
        major = self.bug_results.get("MAJOR", 0)

        # minor = self.get_sonar_severity_number('MINOR') # 次要数量
        # minor = 0 if minor is None else minor
        minor = self.bug_results.get("MINOR", 0)

        # bugs = self.get_sonar_meric_number('bugs') # 本次扫描bug总数
        # bugs = 0 if bugs is None else bugs
        bugs = self.bug_results.get("BUG", 0)
        code_smell = self.bug_results.get("CODE_SMELL", 0)
        vulnerability = self.bug_results.get("VULNERABILITY", 0)

        new_bugs = self.get_sonar_meric_number('new_bugs') #本次扫描相比上次新增bug数
        new_bugs = 0 if new_bugs is None else new_bugs

        status = self.get_sonar_status() # sonar平台判断本次扫描结果，OK 或者 ERROR，作为最终扫描结果参考
        status = "ERROR" if status is None else status
        sonar_url = f"https://sonar.ecarxgroup.com/dashboard?id={self.project_name}" #sonar平台项目链接

        print(f"blocker: {blocker}")
        print(f"critical: {critical}")
        print(f"major: {major}")
        print(f"minor: {minor}")
        print(f"bugs: {bugs}")
        print(f"new_bugs: {new_bugs}")
        print(f"status: {status}")
        print(f"sonar_url: {sonar_url}")
        data = {"bugs": bugs,     # bug数
                "new_bugs": new_bugs,      # 新增bug数
                "minor": minor,         # 次要
                "major": major,         # 主要
                "critical": critical,      # 严重
                "blocker": blocker,       # 阻塞
                "status": status,       # 阻塞
                "code_smell": code_smell,       # 异味
                "vulnerability": vulnerability,       # 异味
                # "sonar_url": str(sonar_url)   # sonar平台项目链接
                }
        # if status.upper() == "OK":
        if int(bugs) == 0 and int(new_bugs) == 0 and int(vulnerability) == 0:
            result = dict(code=CODE.PASS.ID, message=CODE.PASS.NAME)
        else:
            result = dict(code=CODE.FAIL.ID, message=CODE.FAIL.NAME)
        result.update(dict(data=data, prefix="sonar"))

        return result

    def format_to_weixin(self, result_kwargs, url):
        """
            result_kwargs: {'code': -1, 'message': 'FAIL', 
                    'data': {"bugs": bugs,     # bug数
                            "new_bugs": new_bugs,      # 新增bug数
                            "minor": minor,         # 次要
                            "major": major,         # 主要
                            "critical": critical,      # 严重
                            "blocker": blocker,       # 阻塞
                            # "sonar_url": str(sonar_url)   # sonar平台项目链接
                            }}
            url:https://sonar.ecarxgroup.com/dashboard?id=std-data-collect-service-app-meta
        """
        # title = f"#【{self.project_name}】pipeline #{self.buildid} [stage: {self.stage_name}] 统计结果"
        if result_kwargs:
            content = (f"""\n ## [{self.stage_name} Report] [{result_kwargs["message"]}] [报告地址]({url}) """
                    f"""\n > [总bug数]: <font color="{'comment' if result_kwargs["data"]["bugs"] == 0 else 'warning'}">{result_kwargs["data"]["bugs"]}</font> """
                    f"""\n > [新增bug]: <font color="{'comment' if result_kwargs["data"]["new_bugs"] == 0 else 'warning'}">{result_kwargs["data"]["new_bugs"]}</font> """
                    f"""\n > [阻断bug]: <font color="{'comment' if int(result_kwargs["data"]["blocker"]) == 0 else 'warning'}">{result_kwargs["data"]["blocker"]}</font> """
                    f"""\n > [严重bug]: <font color="{'comment' if int(result_kwargs["data"]["critical"]) == 0 else 'warning'}">{result_kwargs["data"]["critical"]}</font> """
                    f"""\n > [主要bug]: <font color="{'comment' if int(result_kwargs["data"]["major"]) == 0 else 'warning'}">{result_kwargs["data"]["major"]}</font> """
                    f"""\n > [次要bug]: <font color="{'comment' if int(result_kwargs["data"]["minor"]) == 0 else 'warning'}">{result_kwargs["data"]["minor"]}</font> """
                    f"""\n > [异味数]: <font color="{'comment' if int(result_kwargs["data"]["code_smell"]) == 0 else 'warning'}">{result_kwargs["data"]["code_smell"]}</font> """
                    f"""\n > [漏洞数]: <font color="{'comment' if int(result_kwargs["data"]["vulnerability"]) == 0 else 'warning'}">{result_kwargs["data"]["vulnerability"]}</font> """
                    # f"""\n > [status]: <font color="{'comment' if result_kwargs["data"]["status"].upper() == "OK" else 'warning'}">{result_kwargs["data"]["status"]}</font> """
                    )
        else:
            content = f"""\n ## [{self.stage_name} Report] \n <font color="warning">当前语言暂时不支持sonar代码扫描</font>"""
        return content